#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "ImageProcessing.hpp"
#include "rknn_yolovX.h"
#include <CL/cl.h>
#include <QProcess>
#include "StateMachine.hpp"

char* MODEL_NAME_1=(char*)"./../../model/yolov8_seg_rk3588.rknn";//模型相对路径
char* MODEL_NAME_2=(char*)"./../../model/yolov5s.rknn";//模型相对路径

char* LABEL_NAME_1=(char*)"./../../model/coco_5_labels_list.txt";//模型相对路径
char* LABEL_NAME_2=(char*)"./../../model/coco_4_labels_list.txt";//模型相对路径
extern QSemaphore semaphore;
extern QSemaphore semaphore_CAPTURE;
RKNN_YOLOVX* RY_thread;
ImageProcessingThread* IP_thread;
int FPS=0,FPS_CNT=0;
StateMachine sm;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowState(Qt::WindowFullScreen);
    
    model_fileName=MODEL_NAME_1;
    model_fileName_str = model_fileName.toStdString();
    ui->lineEdit_4->setText(model_fileName);
    

    // 初始化状态机为 IDLE
    sm.start(std::make_shared<IDLE>());
    qRegisterMetaType<cv::Mat>("cv::Mat&");
    IP_thread = new ImageProcessingThread;
    RY_thread  = new RKNN_YOLOVX(this,1,model_fileName_str,LABEL_NAME_1);
    connect(IP_thread, &ImageProcessingThread::imageProcessed, RY_thread, &RKNN_YOLOVX::run);
    QObject::connect(&timer, &QTimer::timeout, [this]() {
        FPS=FPS_CNT;
        FPS_CNT=0;
        ui->lcdNumber->display(FPS);
        object_detect_result_list od_results = RY_thread->testPool->models.back().get()->od_results;
        w->ui->label_5->clear();
        w->ui->label_6->clear();
        w->ui->label_7->clear();
        // qDebug() << "od_results.count:" << od_results.count;
        for (int i = 0; i < od_results.count; i++){
            object_detect_result det_result = od_results.results[i];
            int x1 = det_result.box.left;
            int y1 = det_result.box.top;
            int x2 = det_result.box.right;
            int y2 = det_result.box.bottom;
            const char *class_name = RY_thread->testPool->models.back().get()->coco_cls_to_name(det_result.cls_id);
            static std::vector<std::string> string_table = {"apple","rotten","insect","moldy","strawberry","persimmon","lemon","sugarorange","pear"};
            for (const auto& str : string_table) {
                if (str == class_name) {
                    qDebug() << "str == class_name";
                    w->ui->label_7->setText(("类别："+str).c_str());
                    w->ui->label_6->setText(("置信度："+std::to_string(det_result.prop)).c_str());
                    w->ui->label_5->setText(("大小："+std::to_string(od_results.results_seg->pixel_cnt)).c_str());
                    break;
                }
            }
            qDebug() << "x1:" << x1 << "y1:" << y1 << "x2:" << x2 << "y2:" << y2 << "prop:" << det_result.prop;
            QString qstring = QString("x1:%1 y1:%2 x2:%3 y2:%4 class:%5 volume:%6 prop:%7")
            .arg(x1)
            .arg(y1)
            .arg(x2)
            .arg(y2)
            .arg(class_name)
            .arg(od_results.results_seg->pixel_cnt)
            .arg(det_result.prop, 0, 'f', 2);
            QListWidgetItem *item = new QListWidgetItem(qstring);
            w->ui->listWidget->addItem(item);
            w->ui->listWidget->scrollToBottom();
        }
        qDebug() << "FPS:" << FPS;
        
    });
    timer.start(1000);
    driver.servo.setspeed(1500*1000);
}
#include <QBuffer>
void MainWindow::updateUI1(const QPixmap& pixmap) {
    image=pixmap;
    ui->label->setPixmap(pixmap);
    FPS_CNT++;
    semaphore_CAPTURE.release();
    semaphore.release();

}
MainWindow::~MainWindow()
{
    disconnect(IP_thread, &ImageProcessingThread::imageProcessed, RY_thread, &RKNN_YOLOVX::run);
    if (IP_thread!=nullptr)delete IP_thread;
    if (RY_thread!=nullptr)delete RY_thread;
    if (ui!=nullptr)delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    std::cout << "on_pushButton_clicked" <<std::endl;
    IP_thread->start();
    sm.processEvent(Event::START);  // IDLE -> TRANSFERRING
}

#include <QFileDialog>
#include <QString>
void MainWindow::on_pushButton_2_clicked()
{
    std::cout << "on_pushButton_2_clicked" <<std::endl;
    model_fileName = QFileDialog::getOpenFileName(this,tr("Open File"), "", tr("All Files (*);;Text Files (*.txt)"));
    model_fileName_str = model_fileName.toStdString();
    if (!model_fileName.isEmpty()) {
        ui->lineEdit_4->setText(model_fileName);
    }
}

void MainWindow::on_dial_valueChanged(int value)
{
    IP_thread->CamCTL->set_camera_exposure(value);
    std::cout << "set_camera_exposure="<< value <<std::endl;
    ui->lineEdit_2->setText(QString::number(value));
}


void MainWindow::on_dial_2_valueChanged(int value)
{
    IP_thread->CamCTL->set_camera_focus(value);
    std::cout << "set_camera_focus="<< value <<std::endl;
    ui->lineEdit->setText(QString::number(value));

}


void MainWindow::on_dial_3_valueChanged(int value)
{
    IP_thread->CamCTL->set_camera_zoom(value);
    std::cout << "set_camera_zoom="<< value <<std::endl;
    ui->lineEdit_3->setText(QString::number(value));
}



void MainWindow::on_pushButton_3_clicked()
{
    sm.processEvent(Event::CAPTURE_T);  // CAPTURE -> IDLE
}


void MainWindow::on_dial_4_valueChanged(int value)
{
    sm.processEvent(Event::CAPTURE_C,value);  // CAPTURE -> CAPTURE

    std::cout << "simple_gap_cnt="<< value <<std::endl;
    ui->lineEdit_5->setText(QString::number(value));
}


void MainWindow::on_checkBox_stateChanged(int arg1)
{
    IP_thread->CamCTL->set_camera_auto_focus(arg1);
    std::cout << "set_camera_auto_focus="<< arg1 <<std::endl;

}


void MainWindow::on_pushButton_4_clicked()
{
    delete this; 
}


void MainWindow::on_pushButton_5_clicked()
{
    // 1. 停止线程并等待其退出
    if (RY_thread != nullptr) {
        RY_thread->stop();  // 请求中断、退出事件循环并等待线程结束
        RY_thread->wait();  // 确保线程已经完全退出
    }

    // 2. 断开信号槽连接
    if (IP_thread != nullptr && RY_thread != nullptr) {
        disconnect(IP_thread, &ImageProcessingThread::imageProcessed, RY_thread, &RKNN_YOLOVX::run);
    }

    // 3. 删除旧的线程对象
    if (RY_thread != nullptr) {
        delete RY_thread;
        RY_thread = nullptr;  // 避免悬空指针
    }
    std::cout << "model_fileName_str="<< model_fileName_str <<std::endl;
    
    // 4. 创建新的线程对象
    RY_thread = new RKNN_YOLOVX(this, 1, model_fileName_str, LABEL_NAME_1);

    // 5. 重新连接信号槽
    connect(IP_thread, &ImageProcessingThread::imageProcessed, RY_thread, &RKNN_YOLOVX::run);
    semaphore.release();

}


void MainWindow::on_pushButton_6_clicked()
{
    static bool enable=0;
    enable=!enable;
    driver.step.enable(enable);
}


void MainWindow::on_checkBox_2_stateChanged(int arg1)
{   
    driver.step.setdir(arg1);
}


void MainWindow::on_dial_5_valueChanged(int value)
{
    driver.step.setspeed(value*1000*1000);
}

void MainWindow::on_pushButton_8_clicked()
{
    
    driver.step.enable(1);
    std::cout << "on_pushButton_8_clicked" <<std::endl;
    QObject::connect(&timer2, &QTimer::timeout, [this](){

        if (times++<(time/100)/2)
        {
            V+=a;
        }else{
            V+=-a;
        }
        
        S+=V;
        driver.step.setspeed((161-V)*1000*1000);
        std::cout << "S:" << S << "V:" << V << "time:" << times << "V_MAX:" << V_MAX <<std::endl;

    });
    timer2.start(100);
    QTimer::singleShot(time, [this]() {
        timer2.stop();
        driver.step.enable(0);
        driver.step.setspeed(0);
    });
}


void MainWindow::on_dial_7_valueChanged(int value)
{
    driver.LED.setbright(value);
}

